package thread;

/**
 * 多线程并发安全问题
 * 当多个线程并发操作同一临界资源，由于线程切换不确定，导致执行顺序出现混乱。严重时可能导致系统
 * 瘫痪。
 * 临界资源:操作该资源的整个过程同一时刻只能由单一线程进行的。
 */
public class SyncDemo {
    public static void main(String[] args) {
        Table table = new Table();
        Thread t1 = new Thread(){
            public void run(){
                while(true){
                    int bean = table.getBean();
                    Thread.yield();
                    System.out.println(getName()+":"+bean);
                }
            }
        };
        Thread t2 = new Thread(){
            public void run(){
                while(true){
                    int bean = table.getBean();
                    Thread.yield();
                    System.out.println(getName()+":"+bean);
                }
            }
        };
        t1.start();
        t2.start();
    }
}

class Table{
    private int beans = 20;

    /**
     * 当一个方法使用关键字synchronized修饰后，这个方法称为"同步方法"。
     * 即:多个线程不能同时在方法内部执行
     * 将并发访问临界资源改为同步(排队，有先后顺序)进行，可有效解决并发安全问题。
     *
     * @return
     */
    public synchronized int getBean(){
        if(beans==0){//桌子上没有豆子了
            throw new RuntimeException("没有豆子了!");
        }
        Thread.yield();//主动放弃该线程CPU时间片，模拟到这里时间片耗尽发生线程切换
        return beans--;
    }
}







